﻿using System;
using System.Linq;
using System.Linq.Expressions;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Repository;
using Loki.Utils;

namespace Loki.UI.Win
{
    public static class LookupEditorExtensions
    {
        public static void Configure<T>(this CheckedComboBoxEdit P_Edit,
                                        Expression<Func<T, object>> P_DisplayMember,
                                        Expression<Func<T, object>> P_ValueMember,
                                        LokiCollection<T> P_DataSource,
                                        string P_EmptyText = null)
        {
            P_Edit.Properties.DisplayMember = ExpressionHelper.Reflect<T>.GetProperty(P_DisplayMember).Name;
            P_Edit.Properties.ValueMember = ExpressionHelper.Reflect<T>.GetProperty(P_ValueMember).Name;
            P_Edit.Properties.NullText = P_EmptyText;
            P_Edit.Properties.DataSource = P_DataSource;
        }

        public static void Configure<T>(this LookUpEdit P_Edit,
                                        Expression<Func<T, object>> P_PopupDisplayMember,
                                        Expression<Func<T, object>> P_DisplayMember,
                                        Expression<Func<T, object>> P_ValueMember,
                                        LokiCollection<T> P_DataSource,
                                        string P_EmptyText = null,
                                        T P_NullItem = default(T))
        {
            P_Edit.Properties.AutoHeight = false;
            P_Edit.Properties.Buttons.Clear();
            P_Edit.Properties.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
            new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)});
            P_Edit.Properties.Columns.Clear();
            P_Edit.Properties.Columns.AddRange(new DevExpress.XtraEditors.Controls.LookUpColumnInfo[] {
            new DevExpress.XtraEditors.Controls.LookUpColumnInfo(ExpressionHelper.Reflect<T>.GetProperty(P_PopupDisplayMember).Name, "Name", 20, DevExpress.Utils.FormatType.None, "", true, DevExpress.Utils.HorzAlignment.Default, DevExpress.Data.ColumnSortOrder.Ascending)});
            P_Edit.Properties.DisplayMember = ExpressionHelper.Reflect<T>.GetProperty(P_DisplayMember).Name;
            P_Edit.Properties.ShowFooter = false;
            P_Edit.Properties.ShowHeader = false;
            P_Edit.Properties.NullText = P_EmptyText;
            P_Edit.Properties.ValueMember = ExpressionHelper.Reflect<T>.GetProperty(P_ValueMember).Name;

            if (!Object.Equals(P_NullItem, default(T)))
            {
                P_Edit.Properties.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
                P_Edit.EditValueChanging += (s, e) =>
                {
                    if (Object.Equals(e.NewValue, P_ValueMember.Compile()(P_NullItem)))
                        e.NewValue = null;
                };
            }

            P_Edit.Properties.DataSource = P_DataSource;
        }

        public static void Configure<T>(this RepositoryItemLookUpEdit P_Edit,
                                        Expression<Func<T, object>> P_PopupDisplayMember,
                                        Expression<Func<T, object>> P_DisplayMember,
                                        Expression<Func<T, object>> P_ValueMember,
                                        LokiCollection<T> P_DataSource,
                                        string P_EmptyText = null,
                                        T P_NullItem = default(T))
        {
            P_Edit.AutoHeight = false;
            P_Edit.Buttons.Clear();
            P_Edit.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
            new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)});
            P_Edit.Columns.Clear();
            P_Edit.Columns.AddRange(new DevExpress.XtraEditors.Controls.LookUpColumnInfo[] {
            new DevExpress.XtraEditors.Controls.LookUpColumnInfo(ExpressionHelper.Reflect<T>.GetProperty(P_PopupDisplayMember).Name, "Name", 20, DevExpress.Utils.FormatType.None, "", true, DevExpress.Utils.HorzAlignment.Default, DevExpress.Data.ColumnSortOrder.Ascending)});
            P_Edit.DisplayMember = ExpressionHelper.Reflect<T>.GetProperty(P_DisplayMember).Name;
            P_Edit.ShowFooter = false;
            P_Edit.ShowHeader = false;
            P_Edit.NullText = P_EmptyText;
            P_Edit.ValueMember = ExpressionHelper.Reflect<T>.GetProperty(P_ValueMember).Name;

            if (!Object.Equals(P_NullItem, default(T)))
            {
                P_Edit.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
                P_Edit.EditValueChanging += (s, e) =>
                {
                    if (Object.Equals(e.NewValue, P_ValueMember.Compile()(P_NullItem)))
                        e.NewValue = null;
                };
            }

            P_Edit.DataSource = P_DataSource;
        }

        private class EnumTextValue<T>
        {
            public T Value { get; set; }
            public string Text { get; set; }
        }

        public static void ConfigureOnEnum<T>(this LookUpEdit P_Editor, string P_EmptyText = null, bool P_DisplayValue = true)
        {
            var L_ValueList = from x in Enum.GetValues(typeof(T)).OfType<T>()
                              select new EnumTextValue<T>()
                              {
                                  Value = x,
                                  Text = EnumParser<T>.ToText(x)
                              };
            if (P_DisplayValue)
            {
                Configure<EnumTextValue<T>>(P_Editor, x => x.Text, x => x.Value, x => x.Value, new LokiCollection<EnumTextValue<T>>(L_ValueList.ToList()), P_EmptyText);
            }
            else
            {
                Configure<EnumTextValue<T>>(P_Editor, x => x.Text, x => x.Text, x => x.Value, new LokiCollection<EnumTextValue<T>>(L_ValueList.ToList()), P_EmptyText);
            }
        }
    }
}
